import { type PathCommand, type CommandType, type MovePathCommand, BaseCommandType } from './types'

// 路径命令参数长度
const ARG_LENGTH = {
    a: 7,
    c: 6,
    h: 1,
    l: 2,
    m: 2,
    q: 4,
    s: 4,
    t: 2,
    v: 1,
    z: 0,
}

// 匹配路径命令
const SEGMENT_PATTERN = /([astvzqmhlc])([^astvzqmhlc]*)/gi

// 匹配路径参数
const NUMBER = /-?[0-9]*\.?[0-9]+(?:e[-+]?\d+)?/gi

// 解析路径参数
function parseValues(args: string): number[] {
    const numbers = args.match(NUMBER)
    return numbers ? numbers.map(Number) : []
}

/**
 * 解析路径字符串
 * @param path 路径字符串
 * @returns 路径命令数组
 */
export function parsePath(path: string): PathCommand[] {
    const data: PathCommand[] = []
    const p = path.trim()

    // 路径必须以 M 或 m 开头
    if (p[0] !== 'M' && p[0] !== 'm') {
        return data
    }

    p.replace(SEGMENT_PATTERN, (_, command: string, args: string) => {
        const theArgs = parseValues(args)
        let type = command.toLowerCase() as BaseCommandType
        let theCommand = command as CommandType

        if (type === 'm' && theArgs.length > 2) {
            data.push([theCommand, ...theArgs.splice(0, 2)] as MovePathCommand)
            type = 'l'
            theCommand = theCommand === 'm' ? 'l' : 'L'
        }

        const argLen = ARG_LENGTH[type]

        // 非法命令
        if (theArgs.length < argLen) {
            return ''
        }

        data.push([theCommand, ...theArgs.splice(0, argLen)] as PathCommand)

        // 重复命令处理，比如: L 200 200 L 400 200 可以简写为 L 200 200 400 200
        while (argLen && theArgs.length >= argLen) {
            data.push([theCommand, ...theArgs.splice(0, argLen)] as PathCommand)
        }

        return ''
    })
    return data
}
